using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using Avalonia.Media.Imaging;
using CommunityToolkit.Mvvm.ComponentModel;
using Avalonia.Threading;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.Json; 
using System.Buffers;

namespace mas.Models;

// 按头部分类的数据模型
public partial class HeaderData : ObservableObject
{
    public string Header { get; }  // 头部标识

    [ObservableProperty] private Bitmap? _image;  // 该头部对应的图像
    [ObservableProperty] private string _message = "";  // 该头部对应的消息

    public HeaderData(string header)
    {
        Header = header;
    }
}

// UDP服务类：封装所有UDP通信逻辑
public partial class UdpService : ObservableObject
{
    // 对外暴露的头部数据集（供UI绑定）
    public ObservableCollection<HeaderData> HeaderDatas { get; } = new ObservableCollection<HeaderData>();
    // UDP配置属性
    [ObservableProperty]
    private int _imagePort = 9993;
    
    [ObservableProperty]
    private int _messagePort = 9994;
    
    // 状态属性
    [ObservableProperty]
    private bool _isRunning;
    
    [ObservableProperty]
    private string _statusMessage = "UDP服务未运行";

    // 通信对象
    private UdpClient? _imageClient;
    private UdpClient? _messageClient;
    private CancellationTokenSource? _cts;
    
    // 用于重用内存的缓冲区
    private readonly byte[] _imageBuffer = new byte[1024 * 1024]; // 1MB缓冲区
    
    // 事件：通知外部接收到图像（新增header参数）
    public event Action<string, Bitmap?>? ImageReceived;  // 第一个参数为header
    
    // 事件：通知外部接收到消息（新增header参数）
    public event Action<string, string>? MessageReceived;  // 第一个参数为header

    
    // 修改：日志消息集合改为LogMessage类型
    public ObservableCollection<LogMessage> LogMessages { get; } = new ObservableCollection<LogMessage>();
    
    // 启动UDP服务
    public async Task StartAsync(string localIp)
    {
        if (IsRunning) return;
    
        try
        {
            _cts = new CancellationTokenSource();
            
            // 添加日志
            AddLog(LogLevel.Info,"准备启动UDP服务...");
            
            // 解析IP地址（处理无效IP情况）
            if (!IPAddress.TryParse(localIp, out IPAddress? localIpAddress))
            {
                StatusMessage = "启动失败: 无效的IP地址";
                AddLog(LogLevel.Error,StatusMessage);
                return;
            }
    
            // 启动图像接收（绑定指定IP和端口）
            _imageClient = new UdpClient(new IPEndPoint(localIpAddress, ImagePort));  // 绑定IP+端口
            _ = ReceiveImagesAsync(_cts.Token);
    
            // 启动消息接收（绑定指定IP和端口）
            _messageClient = new UdpClient(new IPEndPoint(localIpAddress, MessagePort));  // 绑定IP+端口
            _ = ReceiveMessagesAsync(_cts.Token);
    
            IsRunning = true;
            // 更新状态消息，显示绑定的IP和端口
            StatusMessage = $"UDP服务已启动 - IP: {localIp}, 图像端口: {ImagePort}, 消息端口: {MessagePort}";
            AddLog(LogLevel.Info,StatusMessage);
    
            // 添加 await 解决异步警告（等待空任务完成，不影响逻辑）
            await Task.CompletedTask;
        }
        catch (Exception ex)
        {
            StatusMessage = $"启动失败: {ex.Message}";
            AddLog(LogLevel.Error,StatusMessage);
            // 异常路径同样添加 await
            await Task.CompletedTask;
        }
    }

    // 停止UDP服务
    public void Stop()
    {
        if (!IsRunning) return;

        _cts?.Cancel();
        _imageClient?.Close();
        _messageClient?.Close();
        IsRunning = false;
        StatusMessage = "UDP服务已停止";
        ImageReceived?.Invoke("",null); // 通知清除图像
        MessageReceived?.Invoke("",""); // 通知清除消息
    }

    // 图像接收逻辑（带头部解析）
    private async Task ReceiveImagesAsync(CancellationToken cancellationToken)
    {
        try
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var result = await _imageClient!.ReceiveAsync(cancellationToken);
                byte[] buffer = result.Buffer;

                // 解析发送方数据包结构：[4字节头部长度][头部字符串][图像数据]
                if (buffer.Length < sizeof(uint))
                {
                    StatusMessage = "数据包格式错误：长度不足";
                    AddLog(LogLevel.Warning,StatusMessage);  
                    continue;
                }

                uint headerLength = BitConverter.ToUInt32(buffer, 0);
                int headerOffset = sizeof(uint);

                if (headerOffset + headerLength > buffer.Length)
                {
                    StatusMessage = $"数据包格式错误：头部长度({headerLength})超出缓冲区";
                    AddLog(LogLevel.Warning,StatusMessage);  
                    continue;
                }

                string header = System.Text.Encoding.UTF8.GetString(buffer, headerOffset, (int)headerLength);
                int imageDataOffset = headerOffset + (int)headerLength;
                int imageDataLength = buffer.Length - imageDataOffset;
                
                // 在UI线程更新HeaderDatas（避免跨线程异常）
                await Dispatcher.UIThread.InvokeAsync(() =>
                {
                    // 使用共享缓冲区减少内存分配
                    if (imageDataLength <= _imageBuffer.Length)
                    {
                        Buffer.BlockCopy(buffer, imageDataOffset, _imageBuffer, 0, imageDataLength);
                        
                        using (var ms = new MemoryStream(_imageBuffer, 0, imageDataLength))
                        {
                            ms.Position = 0;
                            var bitmap = new Bitmap(ms);
                            
                            // 查找或创建头部数据
                            var headerData = HeaderDatas.FirstOrDefault(hd => hd.Header == header);
                            if (headerData == null)
                            {
                                headerData = new HeaderData(header);
                                HeaderDatas.Add(headerData);  // 添加新头部
                            }
                            headerData.Image = bitmap;  // 更新图像
                            StatusMessage = $"收到图像: 头部={header}, 大小={imageDataLength}字节";
                            AddLog(LogLevel.Info,StatusMessage);  
                        }
                    }
                    else
                    {
                        // 如果图像太大，使用原始方法
                        byte[] imageData = new byte[imageDataLength];
                        Array.Copy(buffer, imageDataOffset, imageData, 0, imageData.Length);
                        
                        using (var ms = new MemoryStream(imageData))
                        {
                            ms.Position = 0;
                            var bitmap = new Bitmap(ms);
                            
                            // 查找或创建头部数据
                            var headerData = HeaderDatas.FirstOrDefault(hd => hd.Header == header);
                            if (headerData == null)
                            {
                                headerData = new HeaderData(header);
                                HeaderDatas.Add(headerData);  // 添加新头部
                            }
                            headerData.Image = bitmap;  // 更新图像
                            StatusMessage = $"收到图像: 头部={header}, 大小={imageData.Length}字节";
                            AddLog(LogLevel.Info,StatusMessage);  
                        }
                    }
                });
            }
        }
        catch (OperationCanceledException) { /* 正常取消 */ }
        catch (Exception ex)
        {
            StatusMessage = $"图像接收错误: {ex.Message}";
            AddLog(LogLevel.Error,StatusMessage);  
        }
    }

    // 消息接收逻辑
    private async Task ReceiveMessagesAsync(CancellationToken cancellationToken)
    {
        try
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var result = await _messageClient!.ReceiveAsync(cancellationToken);
                byte[] buffer = result.Buffer;
                // 解析消息数据包结构（与图像数据包格式一致）
                if (buffer.Length < sizeof(uint))
                {
                    StatusMessage = "消息数据包格式错误：长度不足";
                    AddLog(LogLevel.Warning,StatusMessage); 
                    continue;
                }

                uint headerLength = BitConverter.ToUInt32(buffer, 0);
                int headerOffset = sizeof(uint);

                if (headerOffset + headerLength > buffer.Length)
                {
                    StatusMessage = $"消息数据包格式错误：头部长度({headerLength})超出缓冲区";
                    AddLog(LogLevel.Warning,StatusMessage);  
                    continue;
                }

                // 提取header和消息数据
                string header = System.Text.Encoding.UTF8.GetString(buffer, headerOffset, (int)headerLength);
                int messageDataOffset = headerOffset + (int)headerLength;
                byte[] messageData = new byte[buffer.Length - messageDataOffset];
                Array.Copy(buffer, messageDataOffset, messageData, 0, messageData.Length);
                string message = System.Text.Encoding.UTF8.GetString(messageData);

                // 在UI线程更新HeaderDatas（避免跨线程异常）
                Dispatcher.UIThread.Post(() =>
                {
                    // 查找或创建头部数据
                    var headerData = HeaderDatas.FirstOrDefault(hd => hd.Header == header);
                    if (headerData == null)
                    {
                        headerData = new HeaderData(header);
                        HeaderDatas.Add(headerData); // 添加新头部
                    }

                    headerData.Message = message; // 更新消息
                    StatusMessage = $"收到消息: 头部={header}, 内容={message}";
                    AddLog(LogLevel.Info,StatusMessage);  
                });

                MessageReceived?.Invoke(header, message);  // 传递header和消息
            }
        }
        catch (OperationCanceledException) { /* 正常取消 */ }
        catch (Exception ex)
        {
            StatusMessage = $"消息接收错误: {ex.Message}";
            AddLog(LogLevel.Error,StatusMessage);  
        }
    }
    
    // 添加带日志级别的日志方法（限制最大日志数量为500条）
    private void AddLog(LogLevel level, string message)
    {
        var logMessage = new LogMessage(level, message);
    
        // 在UI线程添加日志
        Dispatcher.UIThread.Post(() =>
        {
            LogMessages.Add(logMessage);
            // 限制日志总数为500条，避免内存占用过大
            while (LogMessages.Count > 500)
                LogMessages.RemoveAt(0);
        }, DispatcherPriority.Background); // 使用Background优先级，避免阻塞UI
    }
    
    // 获取指定Header的JSON字段
    public List<string> GetJsonFieldsForHeader(string header)
    {
        var headerData = HeaderDatas.FirstOrDefault(hd => hd.Header == header);
        if (headerData == null || string.IsNullOrEmpty(headerData.Message))
            return new List<string>();

        return ParseJsonFields(headerData.Message);
    }
    // JSON字段解析核心方法
    private List<string> ParseJsonFields(string json)
    {
        var fields = new List<string>();
        try
        {
            using var doc = JsonDocument.Parse(json);
            ExtractFields(doc.RootElement, "", fields);
        }
        catch (Exception ex)
        {
            AddLog(LogLevel.Error, $"JSON解析失败: {ex.Message}");
            fields.Add("解析错误");
        }
        return fields;
    }
    // 递归提取JSON字段名
    private void ExtractFields(JsonElement element, string parentPath, List<string> fields)
    {
        if (element.ValueKind == JsonValueKind.Object)
        {
            foreach (var prop in element.EnumerateObject())
            {
                string fieldName = string.IsNullOrEmpty(parentPath) ? prop.Name : $"{parentPath}.{prop.Name}";
                fields.Add(fieldName);
                ExtractFields(prop.Value, fieldName, fields);
            }
        }
        else if (element.ValueKind == JsonValueKind.Array)
        {
            int index = 0;
            foreach (var item in element.EnumerateArray())
            {
                string arrayField = $"{parentPath}[{index}]";
                fields.Add(arrayField);
                ExtractFields(item, arrayField, fields);
                index++;
            }
        }
    }
}
